#!/usr/bin/python

from pyparsing import * #Literal, Word, Group, Dict, OneOrMore, ZeroOrMore, alphas, alphanums, nums, delimitedList, Combine

output = """
Plan hash value: 51563070
 
------------------------------------------------------------------------------

| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |         |     6 |   114 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |         |     6 |   114 |     3   (0)| 00:00:01 |
|*  2 |   TABLE ACCESS FULL| COURSES |     6 |    90 |     3   (0)| 00:00:01 |
|*  3 |   INDEX UNIQUE SCAN| PK_STUD |     1 |     4 |     0   (0)| 00:00:01 |
------------------------------------------------------------------------------
 
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
 
   1 - SEL$1
   2 - SEL$1 / C@SEL$1
   3 - SEL$1 / S@SEL$1
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - filter("YEAR">1997)
   3 - access("S"."STUDENTID"="C"."STUDENTID")
   4 - filter("STUDENTS"."STUDENTID"="COURSES"."STUDENTID" AND 
                "STUDENTS"."GPA">3 OR "COURSES"."SEMESTER"='FALL')

 
Column Projection Information (identified by operation id):
-----------------------------------------------------------
 
   1 - "C"."SEMESTER"[VARCHAR2,10], "S"."STUDENTID"[NUMBER,22]
 
   2 - "C"."STUDENTID"[NUMBER,22], "C"."SEMESTER"[VARCHAR2,10]
 
   3 - "S"."STUDENTID"[NUMBER,22]
    
   1 - "STUDENTS"."NAME"[VARCHAR2,25], 
       "COURSES"."COURSENUMBER"[VARCHAR2,15]
               
   2 - "STUDENTS"."STUDENTID"[NUMBER,22], 
       "STUDENTS"."NAME"[VARCHAR2,25], "STUDENTS"."GPA"[NUMBER,22]
                          
   3 - "COURSES"."COURSENUMBER"[VARCHAR2,15]


"""

#parsing output
word            = Word(alphanums + '()%:_*')
underline       = OneOrMore(Word('-')).suppress()
number          = Word(nums).setParseAction( lambda s,l,t: int(t[0]) )
vert            = Literal("|").suppress()

hashValue       = Literal('Plan hash value:').suppress() + number.setResultsName("hash_value") 

headContent     = Combine( word + Optional(White() + word) )
columnHeader    = Group( vert + delimitedList(headContent, "|") + vert )
heading         = underline + columnHeader.suppress() + underline

white           = White().setParseAction( lambda s,l,t: len(t[0]) )

#Contents of de Execution Plan Display
# Id | Cost(%CPU) | Time | (indentation)Operation | Name
planContent     = Combine( Optional('*' + White().suppress()) + number) + vert  \
                 | Combine( number + White().suppress() + ('(') + number + (')') ) + vert \
                 | Combine( number + (':' + number )*2 ) + vert \
                 | Combine( (ZeroOrMore(white) + word) + Optional( OneOrMore( White(ws=' ') + word ) ) ) + vert \
                 | White(ws=' ') + vert 
planLines       = Group( vert + delimitedList( Group( OneOrMore(planContent) ), "|") ).setResultsName("plan_lines")  + underline


queryBlock      = Literal('Query Block Name').suppress() + SkipTo(LineEnd()).suppress() + underline
queryContent    = Group(OneOrMore(Group( number + Suppress('-') + SkipTo(LineEnd()) ) ) ).setResultsName("query") 

predicInfo      =  Literal('Predicate Information').suppress() + SkipTo(LineEnd()).suppress() + underline
predicContent   = Dict( OneOrMore( Group( number + Suppress('-') + oneOf('filter access') + QuotedString(quoteChar='(', endQuoteChar=')',multiline=True) ) ) ).setResultsName("predic") 

projectColumn   =  Literal('Column Projection').suppress() + SkipTo(LineEnd()).suppress() + underline
pCont           = Combine(QuotedString('"') + Optional('.' + QuotedString('"'))+ QuotedString(quoteChar='[', endQuoteChar=']',unquoteResults=False) + Optional(',').suppress() )
projectContent  = Group(OneOrMore(Group( number + Suppress('-') + OneOrMore(pCont) ) ) ).setResultsName("project")

datatable =  hashValue  \
            + heading   \
            + planLines \
            + queryBlock + queryContent             \
            + Optional( predicInfo + predicContent)\
            + projectColumn + projectContent

#data = datatable.parseString(output)
#
#print data
#print data.hash_value
#print data.plan_lines
#print data.query
#print data.predic.items()
#print data.project
